Milestone #1 - Engine Revamp


Below is one of the first two devlogs for the game. They originally appeared on the TIGSource forums and can be found here: https://forums.tigsource.com/index.php?topic=69154Moving forward I will post devlogs on Itch.io and TIGSource.

[May 05, 2020]

Milestone #1 - Engine Revamp

Hello Again! 

It's been just over 4 months since my last post and you may be interested to see how far the game has come in that time. It's a bit of a mixed bag. Gameplay wise, very little has changed. I've instead spent most of my time behind the scenes implementing new systems in my engine. I'd like to look at a few of them today.

Post Processing!

One of the first changes I implemented this year was a post processing or screen effects pipeline. Originally I had set up a basic system which took the final game render (at the Game-boy resolution of 160 by 144 pixels) and scaled it up to fit the size of the game's window.This was accomplished with some render buffers inside of OpenGL, and rendering a quad with a generic shader.

The new system builds upon this allowing multiple shaders to be passed over the render before it is presented in the final window. It might not be initially obvious where this is used. When loading into a level, I now perform a fun little screen transition. It appears as if light is entering the level spreading from top to bottom. This is accomplished using the gradient texture shown below, as well as a bit of shader trickery.


My new shader is aware of my 4 colour pallete, and has stored the colours in order of brightness. When it receives the final render, it re-colours each pixel based on a texture provided to it. If the sampled colour from the texture is white, then no change is made. As the colour approaches black, the shader swaps each colour for a darker one. When the sampled colour is black, then all colours will be shown as the darkest shade. By moving the texture over time, we get this fun little effect which is effective for introducing levels.

You may also of noticed that the fade works in all four directions. As well as going to darker shades, it is possible to do the reverse. Such as the example below, where we start on the brightest shade and return to normal.

  XML Parsing!

The other main change (and one that has taken up most of my time) is the introduction / streamlining of an XML parsing system. I was originally using this as a way of storing level data. Each XML contained a list of resources, and entities (game objects) for a scene. Each Entity has a list of components (game code) that are associated with it. I decided it would be useful for development for me to pass data into components from my level XML. So for example, I could change the player's spawn position, and test the game without having to rebuild my code. I implemented a basic version of this where each components had access to their respective chunk of XML, and would have a unique method to parse it. This would work perfectly fine, however I quickly realised that it didn't scale particularly well and I would end up having to write hundreds of unique parsers that were would only perform simple actions such as converting strings to floats.

The new system is slightly complicated, but works perfectly for my needs. I'll try to explain it briefly, but will happily go into more detail if there's interest. Essentially my system is aware of a bunch of types (i.e. String, Float, Int, Vectors). For each type, I have provided a method that parses from a string, and return a string from a value of that type. When a new class that uses this system (called a ParameterOwner) is created, it registers a map of void pointers. The key of the map is a string which we use to find the XML attribute we care about. The value of the map is a void pointer representing a variable on the object. This was done so that the map could hold data of different (and unrelated) types. Some additional data is stored such as the type of the object. When the new class is told to load an XML, it traverses the map using the key to pull out a string from the XML. It then grabs the type from the map, and uses the provided parse method of that type to put the converted data directly into a variable in that new class.

I hope that makes some sense. Using this implementation means that I can hypothetically set any piece of data in a class without rebuilding the game's code. The system covers most plain old data types, and well as my resource types. This means that components can also now request textures, shaders, audio from the resource manager straight from XML.

I've also introduced the concepts of prefabs, and packages using this system. Prefabs are basically entities that will never perform any logic, an entity can be created by coping the components and children of a prefab. A package is a group of Parameter Owners (i.e. resources, prefabs) grouped by type. I'm using them to store resources that may be used by multiple scenes such as the Player, Camera and some level elements.

Thanks for reading. I apologise for the lack of gifs in the latter half.

Hopefully I'll have some more gameplay related updates soon. Coffee